package com.browse.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.browse.mapper.BrowseRecordMapper;
import com.browse.service.BrowseRecordService;
import com.common.constant.RedisKey;
import com.common.domain.po.VideoBrowseRecord;
import com.common.domain.vo.BrowseRecordListByPageVO;
import com.common.exception.CodeAndMsg;
import com.common.exception.JavaSmException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 路亚
 * @version 0.1
 * @className BrowseRecordServiceImpl
 * @description
 * @date 2024/12/26 17:32
 * @since jdk11
 */
@Service
@RequiredArgsConstructor
public class BrowseRecordServiceImpl extends ServiceImpl<BrowseRecordMapper, VideoBrowseRecord> implements BrowseRecordService {

    private final StringRedisTemplate stringRedisTemplate;

    private final BrowseRecordMapper browseRecordMapper;

    private final ThreadPoolTaskExecutor taskExecutor;

    @Override
    public void addBrowseRecord(String json) {
        String key = RedisKey.BROWSE_RECORD_LIST_KEY;
        if (StringUtils.isEmpty(json)) {
            throw new JavaSmException(CodeAndMsg.PARAM_ERROR);
        }
        VideoBrowseRecord videoBrowseRecord = JSON.parseObject(json, VideoBrowseRecord.class);
        try {
            this.save(videoBrowseRecord);
        } catch (Exception e) {
            e.printStackTrace();
        }
        taskExecutor.execute(() -> {
            stringRedisTemplate.delete(key);
        });
    }

    @Override
    public BrowseRecordListByPageVO listByPage(Integer page) {
        String key = RedisKey.BROWSE_RECORD_LIST_KEY;
        Integer startIndex = (page - 1) * 10;
        Long size = stringRedisTemplate.opsForList().size(key);
        if (size != null && size > 0) {
            Integer pageSize = size.intValue() < 10 * page ? size.intValue() : 10 * page;
            List rangeList = stringRedisTemplate.opsForList().range(key, startIndex, pageSize - 1);
            List<VideoBrowseRecord> videoBrowseRecords = (List<VideoBrowseRecord>) rangeList.stream().map(item -> JSON.parseObject(item.toString(), VideoBrowseRecord.class)).collect(Collectors.toList());
            return new BrowseRecordListByPageVO(size, Long.valueOf(page), videoBrowseRecords, false);
        }
        Page<VideoBrowseRecord> browseRecordPage = new Page<>(page, 10);
        QueryWrapper<VideoBrowseRecord> queryWrapper = new QueryWrapper<>();
        Page<VideoBrowseRecord> pageResult = browseRecordMapper.selectPage(browseRecordPage, queryWrapper);
        taskExecutor.execute(() -> {
            List<VideoBrowseRecord> list = list();
            list.forEach(item -> {
                stringRedisTemplate.opsForList().rightPush(key, JSON.toJSONString(item));
            });
        });
        return new BrowseRecordListByPageVO(pageResult.getTotal(), pageResult.getPages(), pageResult.getRecords(), pageResult.getRecords().isEmpty());
    }

    @Override
    public void deleteById(Long id) {
        VideoBrowseRecord videoBrowseRecord = new VideoBrowseRecord();
        videoBrowseRecord.setId(id);
        videoBrowseRecord.setViewTime(LocalDateTime.now());
        browseRecordMapper.removeById(videoBrowseRecord);
    }
}
